package com.payment.controller.paynotify;

import com.payment.entity.common.UserOrderPackage;
import com.payment.entity.purchase.response.ResponsePurchaseService;
import com.payment.service.*;
import com.payment.service.impl.CommonUtilsServiceImpl;
import com.payment.utils.Constant;
import com.payment.utils.payment.WeiXinPayUtil;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@Api(description = "微信支付回调")
/**
 * 1，使用领科的微信收款账号收款，微信支付回调接口：
 *
 * 2，适用于新的客户：最新版的的领科 H5 和其他想要使用领科收款接口收款的（可以是客户自己的账号或者领科发账号）客户；
 *
 * 3，更新的数据表为：user_order_package_t，user_order_payment_t；
 *
 * 4，更新的数据库为：v-shop
 *
 * @author lm
 * @date 2019/11/06
 */
public class NotifyWeixinController {

    private static Logger logger = Logger.getLogger(NotifyWeixinController.class);

    @Autowired
    private NotificationpaymentService notifiyService;
    @Autowired
    private PartnerService partnerService;
    @Autowired
    private UserOrderPackageService orderService;

    @Autowired
    private CommonUtilsServiceImpl utilsService;

    /***
     * 微信支付结果回调
     * @param request
     * @param
     * @return
     */

    //@PostMapping(value = "/wxNotify")
    @PostMapping("/notify")
    @CrossOrigin
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) {

        if (null != request) {

            try {

                Map rMap = WeiXinPayUtil.getNotifyResult(request);

                String resXml = rMap.get("resXml") + "";
                logger.info("回调给微信的xml：" + rMap.get("resXml") + "");

                String result_code = rMap.get("result_code") + "";
                String return_code = rMap.get("return_code") + "";
                logger.info("结果码:" + result_code + ";返回码：" + return_code);

                if (StringUtils.isNotBlank(rMap.get("out_trade_no") + "") && !(rMap.get("out_trade_no") + "").equalsIgnoreCase("null") &&
                        StringUtils.isNotBlank(rMap.get("total_fee") + "") && !(rMap.get("total_fee") + "").equalsIgnoreCase("null")) {

                    String payId = rMap.get("out_trade_no") + "";
                    //查询payId在数据库有几条记录
                    int payIdCount = 1;
                    if (orderService.findPayIdCount(payId) <= 0) {
                        payIdCount = 1;
                    } else {
                        payIdCount = orderService.findPayIdCount(payId);
                    }

                    //为了从微信拿回来的金额能够直接使用
                    String total_fee = rMap.get("total_fee") + "";
                    //单价
                    float fee = Float.parseFloat(total_fee) / 100 / payIdCount;
                    //总价
                    float fee1 = Float.parseFloat(total_fee) / 100;

                    //支付的总金额相当于付款时的金额
                    String payAmount = String.format("%1.2f", fee1);

                    //支付的总金额/订单条数=每笔订单支付的单价
                    String payUnit = String.format("%1.2f", fee);

                    String settlePrice = "";
                    if (fee <= 0.01) {
                        settlePrice = "0.00";
                    } else {
                        settlePrice = String.format("%1.2f", fee / 7);
                    }

                    logger.info("out_trade_no(订单号)为：" + payId + ";total_fee(金额)为:" + total_fee + ";payAmount为:" + payAmount);
                    //查询订单数据表中此条记录有没有入过库
                    int orderCount = orderService.findPayIdByNotify(payId);

                    if (orderCount <= 0) {

                        if (result_code.equalsIgnoreCase("SUCCESS") && return_code.equalsIgnoreCase("SUCCESS")) {


                            // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t

                            //Integer count = utilsService.updatePayRst(payId, payAmount, rMap.get("fee_type") + "", settlePrice, rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "success", "1", "1");

                            Integer count = utilsService.updatePayRst(payId, payUnit, rMap.get("fee_type") + "", settlePrice, rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "success", "1", "1");

                            if (count <= 0) {

                                //说明订单可能已经移到user_order_package_hist_t去了，我们把结果先插入到user_order_package_hist_t去，然后再写一条记录到user_order_package_t表
                                //Integer co = utilsService.updatePayRstForHist(payId, payAmount, rMap.get("fee_type") + "", rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "success", "1", "1");

                                Integer co = utilsService.updatePayRstForHist(payId, payUnit, rMap.get("fee_type") + "", settlePrice, rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "success", "1", "1");

                                //成功的回调数据入库：根据支付id和金额入库：user_order_payment_hist_t
                                utilsService.updatePaymentForHist(payId, payAmount, rMap.get("fee_type") + "", rMap.get("transaction_id") + "", Constant.PAY_PAYPAL, "success");

                                if (co > 0) {

                                    //将user_order_package_hist_t中订单的记录写入到user_order_package_t去

                                    List<UserOrderPackage> orderList = orderService.queryOrderList(payId);

                                    for (UserOrderPackage o : orderList) {

                                        Integer cou = utilsService.insertOrderToOrderT(o.getPartnerCode(), o.getPartnerName(), o.getDeviceCode(), o.getIccId(), o.getPackageCode(), o.getPackageName(), o.getPackageType(),
                                                o.getBuyType(), o.getPriceType(), o.getSalesType(), o.getGlobalOrder(), o.getOrderPeriod(), o.getRequestOrderId(), o.getOrderNo(), o.getOrderId(), o.getPayId(),
                                                o.getPayAmount(), o.getPayCurrency(), o.getSettlePrice(), o.getPartnerScope(), o.getPackageFee(), o.getExpressFee(), o.getCardFee(), o.getOrderStatus(), o.getPayType(), o.getPayRst(),
                                                o.getIsNotify(), o.getPayAccount(), o.getTransactionId(), o.getCreateDate());

                                        Integer coun = utilsService.insertOrderToPaymentT(o.getPartnerCode(), o.getRequestOrderId(), o.getPayId(), o.getTransactionId(), payAmount, o.getPayCurrency(), o.getPayType(), o.getPayRst());

                                        logger.info(o.getPayId() + "：捞起成功!" + cou + ";" + coun);

                                    }

                                }

                            }
                            //成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
                            utilsService.updatePaymentRst(payId, payAmount, rMap.get("fee_type") + "", rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "success");

                            //成功无卡订单支付结果入库：user_nocard_order_t
                            utilsService.updateNoCardPayRst(payId, "success");

                            //现在拿到支付的结果了，可以去做订购套餐的操作了
                            List<UserOrderPackage> userOrderList = orderService.queryOrderByPayIdAndAmount(payId, payAmount);

                            if (null != userOrderList && userOrderList.size() > 0 && !userOrderList.isEmpty()) {

                                for (UserOrderPackage u : userOrderList) {

                                    if (StringUtils.isNotBlank(u.getPartnerCode())) {

                                        String secret = partnerService.findSecretByPartnerCode(u.getPartnerCode());

                                        if (StringUtils.isNotBlank(secret) && StringUtils.isNotBlank(u.getDeviceCode()) && StringUtils.isNotBlank(u.getPackageName()) && StringUtils.isNotBlank(u.getPackageCode()) &&
                                                StringUtils.isNotBlank(u.getPackageType()) && StringUtils.isNotBlank(u.getOrderPeriod()) && StringUtils.isNotBlank(u.getPayAmount()) && StringUtils.isNotBlank(u.getPayId()) &&
                                                "success".equalsIgnoreCase(u.getPayRst())) {

                                            logger.info(u.getDeviceCode() + "：符合【订购套餐】条件，现在去请求");

                                            //符合要求就去请求订购套餐
                                            ResponsePurchaseService re = utilsService.purchase(u.getPartnerCode(), secret, u.getDeviceCode(), u.getPackageName(), u.getPackageCode(), u.getPackageType(),
                                                    u.getOrderPeriod(), u.getPayAmount(), u.getBuyType(), u.getPriceType(), u.getSalesType(), u.getPayId(), u.getOrderNo(), u.getPayRst(), Constant.PAY_WEIXIN);

                                            if (null != re && true == Constant.RET_CODE_0000.equals(re.getRetCode())) {
                                                logger.info("【订购套餐】成功");
                                            } else {
                                                logger.info("【订购套餐】失败");
                                            }

                                            // 向微信输出处理结果，如果成功（SUCCESS），微信就不会继续调用了，否则微信会连续调用8次
                                            response.setContentType("text/xml");
                                            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                                            out.write(resXml.getBytes());
                                            out.flush();
                                            out.close();

                                        } else {

                                            logger.info("查询到了订单但是主要的订购所需的参数有为空，进入异常处理");

                                        }

                                    } else {
                                        logger.info("查询到了订单但是partnerCode为空，进入异常处理");
                                    }

                                }

                            } else {
                                logger.info("数据库不存在此订单");
                            }

                        } else if (result_code.equalsIgnoreCase("FAIL") || return_code.equalsIgnoreCase("FAIL")) {

                            // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
                            //utilsService.updatePayRst(payId, payAmount, rMap.get("fee_type") + "", settlePrice, rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "fail", "0", "1");

                            utilsService.updatePayRst(payId, payUnit, rMap.get("fee_type") + "", settlePrice, rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "fail", "0", "1");

                            //成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
                            utilsService.updatePaymentRst(payId, payAmount, rMap.get("fee_type") + "", rMap.get("transaction_id") + "", Constant.PAY_WEIXIN, "fail");

                            //成功无卡订单支付结果入库：user_nocard_order_t
                            utilsService.updateNoCardPayRst(payId, "fail");

                            // 向微信输出处理结果，如果不成功（FAIL），微信就不会继续调用了，否则微信会连续调用8次
                            response.setContentType("text/xml");
                            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                            out.write(resXml.getBytes());
                            out.flush();
                            out.close();
                        }
                    } else {
                        logger.info(payId + "：已入库过支付结果！");
                    }

                    //最后去数据库做第三方支付记录的入库
                    int count = notifiyService.findCountByOutTradeno(payId);

                    if (count < 1) {

                        //入库微信流水记录
                        utilsService.insertWeixinResults(rMap.get("bank_type") + "", rMap.get("appid") + "", rMap.get("cash_fee") + "", rMap.get("fee_type") + "", rMap.get("is_subscribe") + "", rMap.get("mch_id") + "",
                                rMap.get("nonce_str") + "", rMap.get("openid") + "", rMap.get("out_trade_no") + "", rMap.get("result_code") + "", rMap.get("return_code") + "", rMap.get("sign") + "",
                                rMap.get("time_end") + "", rMap.get("total_fee") + "", rMap.get("trade_type") + "", rMap.get("transaction_id") + "");
                    }

                } else {

                    logger.info("返回了无用的信息，不予操作！");
                }

            } catch (Exception e) {
                logger.info("处理过程异常：" + e);
            }
        }

    }


    public static void main(String[] args) {

        int payIdCount = 2;
        //为了从微信拿回来的金额能够直接使用
        String total_fee = "6998";
        float fee = Float.parseFloat(total_fee) / 100 / payIdCount;
        //相当于付款时的金额
        String payAmount = String.format("%1.2f", fee);
        String settlePrice = "";

        if (fee <= 0.01) {
            settlePrice = "0.00";
        } else {
            settlePrice = String.format("%1.2f", fee / 7);
        }

        System.out.println("payAmount:" + payAmount + ";settlePrice:" + settlePrice);
    }


}
